/* =====================================================================================
 *       Filename:  communiSys_1018_improve.cc
 *
 *    Description:  use enumeration and greedy
 *
 *        Version:  1.0
 *
 *        Created:  09/17/2012 11:04:50 PM
 * =====================================================================================
 */
#include	<stdio.h>
#include	<limits.h>
#include	<algorithm>

typedef struct node_s
{
    unsigned long bandwidth;
    unsigned long price;
}Node;

bool cmp(const Node &a, const Node &b)
{
    return a.bandwidth < b.bandwidth;
}

static Node arr[104][104];

typedef unsigned long long ull;
int deviceNo, deviceMacs[104];
bool findASolution = false;
unsigned long long bestB, bestP;
unsigned long long currB, currP;
unsigned long maxmin;

void searchASolution(int idx)
{
    for (int i = 0; i < deviceMacs[idx]; ++i)
    {
        if (arr[idx][i].bandwidth > maxmin)
            break;
        currB = arr[idx][i].bandwidth;
        currP = arr[idx][i].price;
        if (findASolution && currB * bestP < bestB * currP)
            continue;
        int k = 1;
        for (k = 1; k < deviceNo; ++k)
        {
            int g = (idx+k) % deviceNo;
            unsigned long priceMin = arr[g][deviceMacs[g]-1].price;
            for (int j = deviceMacs[g]-2; arr[g][j].bandwidth >= currB && j>=0; --j)
                if (arr[g][j].price < priceMin)
                    priceMin = arr[g][j].price;
            currP += priceMin;
            if (findASolution && currB * bestP < bestB * currP)
                break;
        }
        if (k >= deviceNo) {
            if (!findASolution)
                findASolution = true;
            bestB = currB;
            bestP = currP;
        }
    }
}

int main(int argc, char *argv[])
{
    int T;
    while (scanf("%d", &T) == 1)
    {
        while (T--) {
            scanf("%d", &deviceNo);
            maxmin = ULONG_MAX;
            for (int i = 0; i < deviceNo; ++i) {
                scanf("%d", &deviceMacs[i]);
                for (int k = 0; k < deviceMacs[i]; ++k)
                    scanf("%lu%lu", &arr[i][k].bandwidth, &arr[i][k].price);
                std::sort(arr[i], arr[i] + deviceMacs[i], cmp);
                if (maxmin > arr[i][deviceMacs[i]-1].bandwidth)
                    maxmin = arr[i][deviceMacs[i]-1].bandwidth;
            }
            findASolution  = false;
            for (int i = 0; i < deviceNo; ++i) {
                searchASolution(i);
            }
            double res = 1.000000 * bestB / bestP;
            printf ( "%.3f\n", res);
        }
    }
}
